﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pavilion
{
    public class MultiLineCollisionData
    {
        internal event Action Disposed;

        private bool hasChanged;
        private List<Action<MultiLineCollisionData>> collisionChangedActionList;

        internal PhysicalData PhysicalData { get; private set; }
        public Dictionary<MultiLinePhysicalData, List<LineVector>> IntersectedMultiLines { get; private set; }

        public MultiLineCollisionData(PhysicalData physicalData)
        {
            this.PhysicalData = physicalData;
            this.collisionChangedActionList = new List<Action<MultiLineCollisionData>>();

            IntersectedMultiLines = new Dictionary<MultiLinePhysicalData, List<LineVector>>();
        }

        internal void Dispose()
        {
            OnDisposed();

            IntersectedMultiLines = null;
            PhysicalData = null;
            collisionChangedActionList = null;
            Disposed = null;
        }

        internal void RegisterToCollisionChanged(Action<MultiLineCollisionData> collisionChangedAction)
        {
            collisionChangedActionList.Add(collisionChangedAction);
        }

        internal void NotifyIntersectionChanged()
        {
            if (hasChanged)
            {
                hasChanged = false;

                foreach (Action<MultiLineCollisionData> collisionChangedAction in collisionChangedActionList)
                    collisionChangedAction.Invoke(this);
            }
        }

        internal void AddLine(MultiLinePhysicalData multiLineData, LineVector line)
        {
            if (!IntersectedMultiLines.ContainsKey(multiLineData))
                IntersectedMultiLines.Add(multiLineData, new List<LineVector>());

            List<LineVector> interesectedLines = IntersectedMultiLines[multiLineData];

            if (!interesectedLines.Contains(line))
            {
                interesectedLines.Add(line);
                hasChanged = true;
            }
        }

        internal void RemoveLine(MultiLinePhysicalData multiLineData, LineVector line)
        {
            if (!IntersectedMultiLines.ContainsKey(multiLineData))
                return;

            List<LineVector> interesectedLines = IntersectedMultiLines[multiLineData];

            if (interesectedLines.Remove(line))
            {
                if (interesectedLines.Count == 0)
                    IntersectedMultiLines.Remove(multiLineData);

                hasChanged = true;
            }
        }

        public bool IsLineTypeIntersected(LineType lineType)
        {
            return IntersectedMultiLines.Keys.FirstOrDefault(x => x.LineType == lineType) != null;
        }

        private void OnDisposed()
        {
            if (Disposed != null)
                Disposed();
        }
    }
}
